/*
 * @Author: Suo-Yuheng syh15399227325@163.com
 * @Date: 2025-09-09 16:15:35
 * @LastEditors: Suo-Yuheng syh15399227325@163.com
 * @LastEditTime: 2025-09-10 11:57:19
 * @FilePath: /0909/ClientCal.cc
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */

#include <iostream>
#include <string>
#include <time.h>
#include <unistd.h>
#include "Socket.hpp"
#include "Protocol.hpp"

void Usage(const std::string &proc)
{
    std::cout << "\nUsage: " << proc << "  ip port\n"
              << std::endl;
}

// ./clientcal ip port
int main(int argc, char *argv[])
{
    if (argc != 3)
    {
        Usage(argv[0]);
    }
    std::string serverip = argv[1];
    uint16_t serverport = std::stoi(argv[2]);

    // 创建流式套接字
    Sock sockfd;
    sockfd.Socket();
    bool r = sockfd.Connect(serverip, serverport); // 发起连接请求
    if (!r)
        return 1;

    // 连接成功之后，向服务器发送请求，并接收响应
    srand(time(nullptr) ^ getpid());
    int cnt = 1;

    std::string opers = "+-*/%$#&@";

    std::string inbuffer_stream;
    while (cnt <= 10)
    {
        std::cout << "====================第" << cnt++ << "次测试..." << std::endl;

        int x = rand() % 100 + 1;
        usleep(1234);
        int y = rand() % 100;
        usleep(8888);
        char op = opers[rand() % opers.size()];
        Request req(x, y, op);

        req.DebugPrint();

        // 准备发送，序列化、封装报头
        std::string package;
        bool r = req.Serialize(&package);
        package = Encode(package);

        std::cout << "这是最新的发出去的请求： \n"
                  << package;

        // 发送
        int n = write(sockfd.Fd(), package.c_str(), package.size()); // write 的返回值是 成功写入缓冲区的 字节数
        // write(sockfd.Fd(), package.c_str(), package.size());
        // std::cout << "发送结果： " << n << std::endl;

        sleep(1);

        // 接收服务器响应
        char buffer[1280];
        ssize_t n1 = read(sockfd.Fd(), buffer, sizeof(buffer)); // 无法保证能读取到 一个 完整 的报文，但是也有可能一次读到多个报文？？那么就可以while？？
        if (n1 > 0)
        {
            // std::cout << "读取报文成功： " << n1 << std::endl;

            buffer[n1] = '\0';
            inbuffer_stream += buffer; // "len"\n"result code"...

            while (true)
            {
                std::string content;    // 重置content
                r = Decode(inbuffer_stream, &content);
                if (!r)
                {
                    std::cout << "这是一个判断 代码是否 执行到 此处的 Debug " << std::endl;

                    break; // 服务器解析报头失败
                }

                // 服务器解析报头成功，接下来 反序列化
                Response resp;
                r = resp.Deserialize(content);
                if (!r)
                {
                    // exit(2); // 反序列化失败
                    break;
                }

                resp.DebugPrint();
            }
        }

        std::cout << "===============================================" << std::endl;

        // sleep(1);
    }

    sockfd.Close();
    return 0;
}